package org.adream.account.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.adream.account.dao.RealNameAuthDao;
import org.adream.account.dao.RealNameTmpDao;
import org.adream.account.dao.UserDao;
import org.adream.account.entity.UserEntity;
import org.adream.account.util.Constant;
import org.adream.account.util.Utils;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.validation.Assertion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.cas.authentication.CasAuthenticationToken;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import net.coobird.thumbnailator.Thumbnails;

@RequestMapping("/file/")
@Controller
public class DownloadImageController {

	private final static Logger logger = LoggerFactory.getLogger(DownloadImageController.class);

	
	@Value("${image.file.path.userpic}")
	private String userPicPath; // 用户图片
	
	@Value("${image.file.path.syspic}")
	private String sysPicPath; // 系统图片

	@Value("${image.file.path.verifypic}")
	private String verifyPicPath; // 认证图片

	@Value("${image.file.path.helppic}")
	private String helppicPath; // 帮助中心图片
	
	@Value("${file.path.resumefile}")
	private String resumeFilePath;

	@Value("${file.path.annuSurveyfile}")
	private String annuSurveyFilePath;

	@Value("${file.path.stufffile}")
	private String stuffFilePath;

	@Value("${file.path.createConCopyfile}")
	private String createConCopyFilePath;

	@Value("${file.path.excuteConCopyfile}")
	private String excuteConCopyFilePath;
	
	@Autowired
	private RealNameAuthDao authDao;
	
	@Autowired
	private RealNameTmpDao tmpDao;
	
	@Autowired
	private UserDao userDao;

	/**
	 * 浏览图片
	 * @param fileName	图片名称
	 * @param type		图片类型
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "viewimg", method = RequestMethod.GET)
	public void viewimg(@RequestParam("fileName") String fileName, @RequestParam("type") Integer type, 
			HttpServletRequest request, HttpServletResponse response) {
		if(StringUtils.isEmpty(fileName) || type == null) {
			logger.warn("图片浏览失败:参数有误:(");
			return;
		}
		String regex = "^[a-zA-Z0-9_-]+(\\.[a-zA-Z]{3,4})$"; // 带后缀
		String regex2 = "^[a-zA-Z0-9_-]+$";
		if(!fileName.matches(regex) && !fileName.matches(regex2)) { //都不满足
			logger.warn("图片浏览失败：参数非法");
			return;
		}
		
		
		String file = "";
		if (Constant.ONE == type) {
			//用户图片
			file = userPicPath.endsWith(File.separator + "") ? userPicPath : userPicPath + File.separator;			
		} else if (Constant.TWO == type) {
			//系统图片
			file = sysPicPath.endsWith(File.separator + "") ? sysPicPath : sysPicPath + File.separator;
		} else if (Constant.THREE == type) {
			//认证图片
			//有实名管理或认证管理权限或自己可查看认证图片
			Object o = new Object();
			o = request.getUserPrincipal();
			if (o == null || !(o instanceof CasAuthenticationToken)) {
				PrintWriter out = null;
				try {
					response.setContentType("text/html;charset=UTF-8");
					out = response.getWriter();
					out.write("登录信息失效,请重新登录");
					return;
				} catch (IOException e) {
					logger.warn("图片浏览失败:" + e.getMessage());
				} finally {
					if(out != null) {
						out.close();
					}
				}
			}
			//获取登录信息
			CasAuthenticationToken token = (CasAuthenticationToken) o;
			Assertion assertion = token.getAssertion();
			AttributePrincipal principal = assertion.getPrincipal();
			Map<String, Object> map = principal.getAttributes();
			if (StringUtils.isEmpty(map.get("uid"))) {
				PrintWriter out = null;
				try {
					response.setContentType("text/html;charset=UTF-8");
					out = response.getWriter();
					out.write("登录信息失效,请重新登录");
					return;
				} catch (IOException e) {
					logger.warn("图片浏览失败:" + e.getMessage());
				} finally {
					if(out != null) {
						out.close();
					}
				}
			}
			//获取全部权限
			String resIdStr = (String) map.get("resIds");
			//权限为空 || (既没有实名认证管理权限又没有身份认证管理权限)
			if (StringUtils.isEmpty(resIdStr) || 
					(resIdStr.indexOf(Constant.REALNAME_MANAGER_RES_ID) == -1 && 
					 resIdStr.indexOf(Constant.VERIFY_MANAGER_RES_ID) == -1  && 
					 resIdStr.indexOf(Constant.REALNAME_SHOW_RES_ID) == -1
							)) {
				String uid = (String) map.get("uid");
				//通过图片文件查询是否是本人
				Set<String> authUids = authDao.queryUidsByCrePicAndDr(fileName, Constant.ONE);
				if(Utils.isEmptyCollection(authUids) || !authUids.contains(uid)) {
					Set<String> tmpUids = tmpDao.queryUidsByCrePicAndDr(fileName, Constant.ONE);
					if(Utils.isEmptyCollection(tmpUids) || !tmpUids.contains(uid)) {
						PrintWriter out = null;
						try {
							response.setContentType("text/html;charset=UTF-8");
							out = response.getWriter();
							out.write("图片浏览失败:权限不足");
							return;
						} catch (IOException e) {
							logger.warn("图片浏览失败:" + e.getMessage());
						} finally {
							if(out != null) {
								out.close();
							}
						}
					}
				}
			}
			file = verifyPicPath.endsWith(File.separator + "") ? verifyPicPath : verifyPicPath + File.separator;
		}else if(Constant.FOUR == type) {
			//帮助中心图片
			file = helppicPath.endsWith(File.separator + "") ? helppicPath : helppicPath + File.separator;
		}
		file = file + fileName;
		FileInputStream fis = null;
		OutputStream os = null;
		try {
			fis = new FileInputStream(file);
			os = response.getOutputStream();
			int count = 0;
			byte[] buffer = new byte[1024 * 8];
			while ((count = fis.read(buffer)) != -1) {
				os.write(buffer, 0, count);
				os.flush();
			}
		} catch (Exception e) {
			logger.info("图片浏览失败:)");
		} finally {
			try {
				if (fis != null) {
					fis.close();
				}
				if (os != null) {
					os.close();
				}
			} catch (Exception e2) {
				logger.info("图片浏览失败:)");
			}
		}
	}
	
	/**
	 * file/headimg/uid_height*width uid_分辨率访问头像  无头像时使用默认头像
	 * 若无分辨率时,不进行压缩
	 * @param uid
	 * @param response
	 */
	@RequestMapping(value = "headimg/{uidHeightWidth}")
	public void viewimg(@PathVariable("uidHeightWidth") String uidHeightWidth, HttpServletRequest request, HttpServletResponse response) {
		if(StringUtils.isEmpty(uidHeightWidth)) {
			logger.warn("图片浏览失败:参数有误:(");
			return;
		}
		String uid;String file = "";int height = 0;int width = 0;
		if(uidHeightWidth.indexOf("_") != -1) {
			uid = uidHeightWidth.split("_")[0];
			String heightWidth = uidHeightWidth.split("_")[1];
			//heightWidth格式不为 height*width
			if(heightWidth.indexOf("*") == -1 || heightWidth.split("\\*").length != Constant.TWO 
					|| !Utils.isInteger(heightWidth.split("\\*")[0]) || !Utils.isInteger(heightWidth.split("\\*")[1])) {
				logger.warn("图片浏览失败:参数有误:(");
				return;
			}
			height = Integer.parseInt(heightWidth.split("\\*")[0]);
			width = Integer.parseInt(heightWidth.split("\\*")[1]);
		} else {
			uid = uidHeightWidth;
		}
		UserEntity user = userDao.queryUserByUid(uid);
		//判断获取后面带文件分隔符的用户图片路径
		String path = userPicPath.endsWith(File.separator + "") ? userPicPath : userPicPath + File.separator;
		//用户不存在或用户无头像或用户头像不存在 使用默认头像
		if(user == null || StringUtils.isEmpty(user.getHeadimgurl()) || !new File(path + user.getHeadimgurl()).exists()) {
			file = request.getSession().getServletContext().getRealPath("/normal/images/moren.png");
		} else {
			if(uid.equals(uidHeightWidth) || height == 0 || width == 0) {
				file = path + user.getHeadimgurl();			
			} else {
				String headimgurl = user.getHeadimgurl();
				String picName = headimgurl.substring(0, headimgurl.lastIndexOf("."));
				String ext = headimgurl.substring(headimgurl.lastIndexOf("."));
				try {
					//生产缩略图
					Thumbnails.of(path + headimgurl).size(width, height).toFile(path + picName + "_" + height + "x" + width + ext);
					file = path + picName + "_" + height + "x" + width + ext;
				} catch (IOException e) {
					logger.warn("图片浏览失败:)");
					return;
				}
			}
		}
		FileInputStream fis = null;
		OutputStream os = null;
		try {
			fis = new FileInputStream(file);
			os = response.getOutputStream();
			int count = 0;
			byte[] buffer = new byte[1024 * 8];
			while ((count = fis.read(buffer)) != -1) {
				os.write(buffer, 0, count);
				os.flush();
			}
		} catch (Exception e) {
			logger.info("图片浏览失败:)");
		} finally {
			try {
				if (fis != null) {
					fis.close();
				}
				if (os != null) {
					os.close();
				}
				//若生成了图片缩略图
				if(!uid.equals(uidHeightWidth) && height != 0 && width != 0) {
					//删除图片缩略图
					new File(file).delete();
				}
			} catch (Exception e2) {
				logger.info("图片浏览失败:)");
			}
		}
	}
	
	/**
	 * 下载图片
	 * @param request
	 * @param response
	 * @param fileName	文件名称
	 * @param type	文件类型
	 */
	@RequestMapping(value = "download")
	public void download(HttpServletRequest request, HttpServletResponse response,
			@RequestParam("fileName") String fileName, @RequestParam("type") Integer type) {
		InputStream ins = null;
		OutputStream os = null;
		try {
			request.setCharacterEncoding("UTF-8");
			// 获取服务器文件
			String file = "";
			if (Constant.ONE == type) {
				file = resumeFilePath.endsWith(File.separator) ? resumeFilePath : resumeFilePath + File.separator;
			} else if (Constant.TWO == type) {
				file = annuSurveyFilePath.endsWith(File.separator) ? annuSurveyFilePath
						: annuSurveyFilePath + File.separator;
			} else if (Constant.THREE == type) {
				file = stuffFilePath.endsWith(File.separator) ? stuffFilePath : stuffFilePath + File.separator;
			} else if (Constant.FOUR == type) {
				file = createConCopyFilePath.endsWith(File.separator) ? createConCopyFilePath
						: createConCopyFilePath + File.separator;
			} else if (Constant.FIVE == type) {
				file = excuteConCopyFilePath.equals(File.separator) ? excuteConCopyFilePath
						: excuteConCopyFilePath + File.separator;
			}
			file = file + fileName;
			ins = new FileInputStream(file);
			/* 设置文件ContentType类型，这样设置，会自动判断下载文件类型 */
			response.setContentType("multipart/form-data");
			/* 设置文件头：最后一个参数是设置下载文件名 */
			response.setHeader("Content-Disposition",
					"filename=" + new String(new File(file).getName().getBytes("UTF-8"), "ISO8859-1"));
			os = response.getOutputStream();
			byte[] b = new byte[1024];
			int len;
			while ((len = ins.read(b)) > 0) {
				os.write(b, 0, len);
			}
			os.flush();
		} catch (IOException ioe) {
			logger.info("文件下载失败:)");
		} finally {
			try {
				if (os != null) {
					os.close();
				}
				if (ins != null) {
					ins.close();
				}
			} catch (IOException e) {
				logger.error("文件下载失败:" + e.getMessage());
			}
		}
	}
}